package com.example.pt.service;

import com.example.pt.dto.PrivateMessageDTO;
import com.example.pt.entity.PrivateMessage;
import com.example.pt.entity.User;
import com.example.pt.mapper.PrivateMessageMapper;
import com.example.pt.repository.UserRepositories;
import com.example.pt.utils.DownloadUrlUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 私信服务类
 */
@Service
public class PrivateMessageService {

    @Autowired
    private PrivateMessageMapper privateMessageMapper;
    
    @Autowired
    private UserRepositories userRepositories;

    @Autowired
    private DownloadUrlUtils downloadUrlUtils;
    @Autowired
    private UserService userService;

    /**
     * 发送私信
     * @param senderId 发送者ID
     * @param receiverId 接收者ID
     * @param content 消息内容
     * @return 发送的消息
     */
    @Transactional
    public PrivateMessageDTO sendMessage(Integer senderId, Integer receiverId, String content) {
        // 检查接收者是否存在
        User receiver = userRepositories.findByUid(receiverId);
        if (receiver == null) {
            throw new IllegalArgumentException("接收者不存在");
        }
        
        // 检查自己是否存在（安全检查）
        User sender = userRepositories.findByUid(senderId);
        if (sender == null) {
            throw new IllegalArgumentException("发送者不存在");
        }
        
        // 不能给自己发私信
        if (senderId.equals(receiverId)) {
            throw new IllegalArgumentException("不能给自己发私信");
        }
        
        // 创建会话ID（较小ID_较大ID）
        String conversationId = PrivateMessage.generateConversationId(senderId, receiverId);
        
        // 创建私信
        PrivateMessage message = new PrivateMessage();
        message.setSenderId(senderId);
        message.setReceiverId(receiverId);
        message.setContent(content);
        message.setCreateTime(new Date());
        message.setStatus(0); // 0-未读
        message.setConversationId(conversationId);
        
        privateMessageMapper.insert(message);
        
        // 转换为DTO返回
        PrivateMessageDTO dto = convertToDTO(message, senderId);
        
        return dto;
    }
    
    /**
     * 获取与指定用户的聊天记录（30天内）
     * @param userId 当前用户ID
     * @param otherUserId 对方用户ID
     * @return 聊天记录
     */
    @Transactional
    public List<PrivateMessageDTO> getConversationMessages(Integer userId, Integer otherUserId) {
        // 检查对方用户是否存在
        User otherUser = userRepositories.findByUid(otherUserId);
        if (otherUser == null) {
            throw new IllegalArgumentException("用户不存在");
        }
        
        // 创建会话ID
        String conversationId = PrivateMessage.generateConversationId(userId, otherUserId);
        
        // 查询30天内的聊天记录
        List<PrivateMessage> messages = privateMessageMapper.selectMessagesByConversationId(conversationId, 30);
        
        // 将接收到的消息标记为已读
        privateMessageMapper.markConversationAsRead(userId, conversationId);
        
        // 转换为DTO
        List<PrivateMessageDTO> result = messages.stream()
            .map(message -> convertToDTO(message, userId))
            .collect(Collectors.toList());

        for(PrivateMessageDTO dto : result) {
            dto.setReceiverHeadshot(downloadUrlUtils.generateDownloadLink(dto.getReceiverId()));
            dto.setSenderHeadshot(downloadUrlUtils.generateDownloadLink(dto.getSenderId()));
        }
        
        return result;
    }
    
    /**
     * 获取用户的会话列表
     * @param userId 用户ID
     * @return 会话列表
     */
    public List<PrivateMessageDTO> getConversationList(Integer userId) {
        // 获取最新消息列表
        List<PrivateMessage> latestMessages = privateMessageMapper.selectLatestMessagesByUserId(userId);
        List<PrivateMessageDTO> result = new ArrayList<>();
        
        for (PrivateMessage message : latestMessages) {
            PrivateMessageDTO dto = convertToDTO(message, userId);

            if(userId.equals(dto.getSenderId())) {
                dto.setSenderId(userId);
                dto.setReceiverId(message.getReceiverId());

                String senderHeadshot = downloadUrlUtils.generateDownloadLink(dto.getSenderId());
                String receiverHeadshot = downloadUrlUtils.generateDownloadLink(dto.getReceiverId());

                dto.setSenderHeadshot(senderHeadshot);
                dto.setReceiverHeadshot(receiverHeadshot);

            }
            if(userId.equals(dto.getReceiverId())) {
                dto.setReceiverId(message.getSenderId());
                dto.setSenderId(userId);
                dto.setReceiverName(userService.searchByUid(message.getSenderId()).getUsername());
                dto.setSenderName(userService.searchByUid(userId).getUsername());


                String senderHeadshot = downloadUrlUtils.generateDownloadLink(dto.getSenderId());
                String receiverHeadshot = downloadUrlUtils.generateDownloadLink(dto.getReceiverId());

                dto.setSenderHeadshot(senderHeadshot);
                dto.setReceiverHeadshot(receiverHeadshot);

            }

            
            // 查询未读消息数
            int unreadCount = privateMessageMapper.countUnreadMessages(userId, message.getConversationId());
            
            // 如果是自己发的消息，未读数应该是0
            if (message.getSenderId().equals(userId)) {
                unreadCount = 0;
            }
            
            // 设置未读消息数（可以在前端显示）
            dto.setStatus(unreadCount > 0 ? 0 : 1); // 0-有未读，1-全部已读
            
            result.add(dto);
        }
        
        return result;
    }
    
    /**
     * 标记消息为已读
     * @param messageId 消息ID
     * @param userId 用户ID（接收者）
     * @return 是否成功
     */
    @Transactional
    public boolean markMessageAsRead(Integer messageId, Integer userId) {
        PrivateMessage message = privateMessageMapper.selectById(messageId);
        
        // 检查消息是否存在且当前用户是接收者
        if (message == null || !message.getReceiverId().equals(userId)) {
            return false;
        }
        
        // 标记为已读
        privateMessageMapper.markMessageAsRead(messageId);
        
        return true;
    }
    
    /**
     * 标记会话为已读
     * @param userId 用户ID（接收者）
     * @param otherUserId 对方用户ID
     * @return 是否成功
     */
    @Transactional
    public boolean markConversationAsRead(Integer userId, Integer otherUserId) {
        // 创建会话ID
        String conversationId = PrivateMessage.generateConversationId(userId, otherUserId);
        
        // 标记会话中的所有消息为已读
        privateMessageMapper.markConversationAsRead(userId, conversationId);
        
        return true;
    }
    
    /**
     * 将消息实体转换为DTO
     * @param message 消息实体
     * @param currentUserId 当前用户ID
     * @return 消息DTO
     */
    private PrivateMessageDTO convertToDTO(PrivateMessage message, Integer currentUserId) {

        PrivateMessageDTO dto = new PrivateMessageDTO();
        dto.setMessageId(message.getMessageId());
        dto.setContent(message.getContent());
        dto.setCreateTime(message.getCreateTime());
        dto.setStatus(message.getStatus());
        dto.setConversationId(message.getConversationId());


        if(message.getReceiverId().equals(currentUserId)) {
            dto.setSenderId(message.getReceiverId());
            dto.setReceiverId(message.getSenderId());
        }else{
            dto.setReceiverId(message.getReceiverId());
            dto.setSenderId(message.getSenderId());
        }

        
        // 设置消息方向（是否由当前用户发送）
        dto.setFromSelf(message.getSenderId().equals(currentUserId));
        
        // 获取发送者信息
        User sender = userRepositories.findByUid(message.getSenderId());
        if (sender != null) {
            dto.setSenderName(sender.getUsername());
            dto.setSenderHeadshot(sender.getHeadshot());
            dto.setSenderStatus(sender.getStatus());
        }
        
        // 获取接收者信息
        User receiver = userRepositories.findByUid(message.getReceiverId());
        if (receiver != null) {
            dto.setReceiverName(receiver.getUsername());
            dto.setReceiverHeadshot(receiver.getHeadshot());
            dto.setReceiverStatus(receiver.getStatus());
        }
        
        return dto;
    }
} 